package server2;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import server.HttpServlet;
import server2.mapper.mapper;
import server2.mapper.mapperHost;
import server2.mapper.mappercontext;
import server2.mapper.mapperwrapper;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public  class BootStrap {

    mapper m = new mapper();



    //监听端口
    Integer port = 8088;

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public BootStrap(Integer port) {
        this.port = port;
    }

    //start方法，创建启动socket
    public void start() throws IOException {
        try {
            loadServlet();
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        // 定义一个线程池
        int corePoolSize = 10;
        int maximumPoolSize =50;
        long keepAliveTime = 100L;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();


        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );

        // 定义一个线程池2



        ThreadPoolExecutor threadPoolExecutor2 = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );

        //根据端口数启动多个监听

        List<mapperHost> hosts = m.getHosts();
        for(mapperHost host:hosts){
            port = Integer.parseInt(host.getHost());
            System.out.println("监听"+port);
            server2.serverSocket serverSocket1 = new serverSocket(port,host);
            ThreadPoolExecutor threadPoolExecutor1 = threadPool.getthreadPoolExecutor();
            threadPoolExecutor1.execute(serverSocket1);

         /*   while (true) {
                Socket socket = serverSocket.accept();
                RequestProcessor requestProcessor = new RequestProcessor(socket, host);
                threadPoolExecutor.execute(requestProcessor);
        }*/



         /*   InputStream inputStream = socket.getInputStream();

            Request request = new Request(inputStream);
            Response response = new Response(socket.getOutputStream());
            response.outputHtml(request.getUrl());
            //String s = HttpProtocolUtil.getHttpHeader200(Data.length()) + Data;
            //outputStream.write(s.getBytes());
            socket.close();*/
        }


    }


    //主方法启动程序

    public static void main(String[] args) {

        BootStrap bootStrap = new BootStrap(8088);
        try {
            bootStrap.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 解析web。xml
     */
   private mapperHost  parseWebXml(InputStream resourceAsStream,File file) throws DocumentException, ClassNotFoundException, IllegalAccessException, InstantiationException {

       mappercontext context = new mappercontext();
       mapperHost ho = new mapperHost();
       // InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("web.xml");
       SAXReader saxReader = new SAXReader();
       Document document = saxReader.read(resourceAsStream);
       Element rootElement = document.getRootElement();

       List<Element> web = rootElement.selectNodes("//web-app");
       String name = web.get(0).attributeValue("name");

       List<Element> host = rootElement.selectNodes("//host");
       String hoststr = host.get(0).getText();


       List<Element> selectNodes = rootElement.selectNodes("//servlet");
       for (int i = 0; i < selectNodes.size(); i++) {
           Element element = selectNodes.get(i);
           // <servlet-name>lagou</servlet-name>
           Element servletnameElement = (Element) element.selectSingleNode("servlet-name");
           String servletName = servletnameElement.getStringValue();
           // <servlet-class>server.LagouServlet</servlet-class>
           Element servletclassElement = (Element) element.selectSingleNode("servlet-class");
           String servletClass = servletclassElement.getStringValue();


           // 根据servlet-name的值找到url-pattern
           Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
           // /lagou
           String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();

           String s = file + "\\target\\classes\\" + servletClass;


           MyClassLoader myClassLoader = new MyClassLoader();
           Class<?> aClass = myClassLoader.findClass(file + "\\target\\classes\\", servletClass);

           mapperwrapper wrapper = new mapperwrapper();
           wrapper.setName(urlPattern);
           wrapper.setServlet((HttpServlet) aClass.newInstance());


           List<mapperwrapper> wrappers = context.getWrappers();
           if(wrappers == null){
               ArrayList<mapperwrapper> objects = new ArrayList<>();
               objects.add(wrapper);
               context.setWrappers(objects);
           }else{
               wrappers.add(wrapper);
           }

       }
        context.setName(name);
       List<mappercontext> contexts = ho.getContexts();
       if(contexts == null ){
           ArrayList<mappercontext>  contextss= new ArrayList<>();
           contextss.add(context);
           ho.setContexts(contextss);
       }else{
           contexts.add(context);
       }

       ho.setHost(hoststr);
       return ho;
   }


    /**
     * 加载解析web.xml，初始化Servlet
     */

    private Map<String, HttpServlet> servletMap = new HashMap<String, HttpServlet>();

    private Map<String, HttpServlet> classes = new HashMap<String, HttpServlet>();

    private void loadServlet() throws DocumentException, FileNotFoundException {
        String path = this.getClass().getResource("").getPath();
        String[] split = path.split("target/classes/server2/");
        String s = split[0] + "webapps";
        //遍历项目
        File file = new File(s);
        File[] files = file.listFiles();
        for (File f : files) {
            File[] files1 = f.listFiles();
            for (File f2 : files1) {
                String name = f2.getName();
                if (name.equals("web.xml")) {
                    //读取路径存入到mapper中
                    FileInputStream fileInputStream = new FileInputStream(f2);
                    try {
                        mapperHost mapperHost = parseWebXml(fileInputStream,f);
                        List<server2.mapper.mapperHost> hosts = m.getHosts();
                        if(hosts == null){
                            ArrayList<server2.mapper.mapperHost> mapperHosts = new ArrayList<>();
                            mapperHosts.add(mapperHost);
                            m.setHosts(mapperHosts);
                        }else{
                            hosts.add(mapperHost);
                        }

                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
                //根据mapper里面的配置类实例化servle对象,存入到wrapper中



        /* <--------------------实例化servlet-------------------->
              *  <--------------------实例化servlet-------------------->
              1、加载目标项目读取配置文件web.xml
              * 2、加载目标项目，实例化servlet
              * */
           // servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance());

        /*   String path = this.getClass().getResource("").getPath();
           String[] split = path.split("target/classes/server2/");
           String s = split[0] + "webapps";
           //遍历项目
           File file = new File(s);
           File[] files = file.listFiles();
           for (File f : files) {
               if(f.getName() == "web.xml"){
                   //读取路径存入到mapper中

               }*/
               //根据mapper里面的配置类实例化servle对象,存入到wrapper中



       }

    private void getAllServletClass(File f2) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        File[] files = f2.listFiles();
      for(File f :files ){
          if(f.isDirectory()){
              getAllServletClass(f);
          }else{
              if(f.getName().contains(".class")  && f.getClass().isAssignableFrom(HttpServlet.class)){
                  classes.put(f.getPath(),(HttpServlet) Class.forName(f.getPath()).newInstance());
              }
          }
      }
    }

}